package com.sharelords.biz.util;

import com.sharelords.biz.Biz;
import com.sharelords.biz.util.InvokeUtil.Child;
import tk.mybatis.mapper.common.Mapper;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;

/**
 * @author 千古龙少
 * @Description: 通用泛型获取，biz需要四个泛型，分别获取class类型
 * @date 2019年9月15日 下午3:19:33
 */
public class BizGenericsUtil {

    public BizGenericsUtil(Class<?> clazz) {
        this.getParentGenerics(clazz);
    }

    /**
     * 业务模型
     */
    private Class<?> boClass;
    /**
     * 数据模型
     */
    private Class<?> entityClass;
    /**
     * 主键
     */
    private Class<?> dClass;
    /**
     * 数据交互接口
     */
    private Class<?> daoClass;

    public Class<?> getBoClass() {
        return boClass;
    }

    public Class<?> getEntityClass() {
        return entityClass;
    }

    public Class<?> getdClass() {
        return dClass;
    }

    public Class<?> getDaoClass() {
        return daoClass;
    }

    @SuppressWarnings("unchecked")
    private <Bo, Entity, D, Dao extends Mapper<Entity>> void getParentGenerics(Class<?> destClazz) {
        // 得到父类的泛型
        Type[] typeArr = destClazz.getGenericInterfaces();
        Type sType = InvokeUtil.searchFromList(Arrays.asList(typeArr), new Child<Type, Type>() {
            @Override
            public Type group(Type type) {
                Type rawType = ((ParameterizedType) type).getRawType();
                Type bizType = Biz.class;
                if (rawType.equals(bizType)) {
                    return type;
                }

                return null;
            }
        });
        if (sType == null) {
            return;
        }

        // 得到实际的类型参数数组
        Type[] generics = ((ParameterizedType) sType).getActualTypeArguments();
        // 得到第一个泛型的Class
        boClass = (Class<Bo>) generics[0];
        // 得到第二个泛型的Class
        entityClass = (Class<Entity>) generics[1];
        // 得到第三个泛型Class
        dClass = (Class<D>) generics[2];
        // 得到第四个泛型class
        daoClass = (Class<Dao>) generics[3];
    }

}
